﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PloobsEngine.SceneControl;
using PloobsEngine.Physics;
using PloobsEngine.Factories;
using PloobsEngine;
using PloobsEngine.IA.Locomotion;
using PloobsEngine.Cameras;
using Microsoft.Xna.Framework;
using PloobsEngine.Input;
using PloobsEngine.Features;
using PloobsEngine.Draw;
using PloobsEngine.Modelo;
using PloobsEngine.Physics.XJigLib;
using PloobsEngine.Material;
using PloobsEngineDemo3;
using PloobsEngine.Commands;
using PloobsEngine.Light;
using Microsoft.Xna.Framework.Graphics;

namespace Etapa1.Screens
{
    public class SteerScreen : SceneScreen
    {
        private JigLibxWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;
        private Manager manager;
        BasicLocomotionAgent bla;
        ICamera cam;        
        
        Bnoerj.AI.Steering.Pedestrian.PedestrianPlugIn pedestrian;

        public SteerScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new JigLibxWorld(new GenericDebugDrawn(engine));
            physicWorld.isDebugDraw = true;
            mundo = new BrutalForceWorld(physicWorld);
            manager = engine.Manager;            
            engine.Game.IsFixedTimeStep = true;
        }
       
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {                      
			// invoke selected PlugIn's Update method
            pedestrian.Update(EngineStuff.Clock.TotalSimulationTime, EngineStuff.Clock.ElapsedSimulationTime);
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);					
        }

        public override void LoadContent(EngineStuff es)
        {            

            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            Picking pk = new Picking();
            engine.AddComponent(pk);
            
            base.LoadContent(es);

            Drawing.setClearEveryFrame(false);

            pedestrian = new Bnoerj.AI.Steering.Pedestrian.PedestrianPlugIn(mundo,engine);
            pedestrian.Open();          

            {
                //SimpleModel sm = new SimpleModel("..\\Content\\Model\\senario", "..\\Content\\Textures\\brickwork", "..\\Content\\Textures\\brickwork_normal");
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(sm, Matrix.Identity, Vector3.Zero);
                pi.isMotionLess = true;
                IShader shader = new NormalDeferred();
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                IObject obj4 = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj4);
            }

            {
                //SimpleModel sm = new SimpleModel("..\\Content\\Model\\senario", "..\\Content\\Textures\\brickwork", "..\\Content\\Textures\\brickwork_normal");
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\block", "..\\Content\\Textures\\caixaTex");
                sm.LoadModelo();
                IPhysicObject pi = new CharacterObject(new Vector3(100,20,50),(float) Math.Sqrt(2), 1,new Vector3(5,5,5));                
                IShader shader = new NormalDeferred();
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                IObject obj4 = new SimpleObject(mat, pi, sm);
                bla = new BasicLocomotionAgent(obj4);
                bla.Locomotion.MaxSpeed = 50;
                bla.Locomotion.MaxRotation = 10;
                bla.Locomotion.MaxAceleration = 10;                
                mundo.AddObject(obj4);
            }


            cam = new CameraFirstPerson(true);
            //cam = new StaticCamera(new Vector3(100,50,100), Vector3.Zero);
            cam.FarPlane = 3000;

            
            LightThrow lt = new LightThrow(mundo, engine);       

            #region Shadow LIGHT
            DirectionalLight ld = new DirectionalLight(new Vector3(-1), Color.White);
            DirectionalLight ld2 = new DirectionalLight(new Vector3(-0.3f, -1, -0.3f), Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Down, Color.White);
            ld.LightIntensity = 0.3f;
            ld2.LightIntensity = 0.3f;
            ld3.LightIntensity = 0.3f;
            ld.CastShadown = true;
            ld2.CastShadown = false;
            ld3.CastShadown = false;
            mundo.AddLight(ld);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            #endregion            
         
            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);           

            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;

            PickingParameters pp = new PickingParameters(cam, mundo, MouseButtons.RightButton);
            pp.Method = SegmentInterceptMethod.ALL;
            PickingRedirectorCallbackObserver prc = new PickingRedirectorCallbackObserver();
            prc.redirectPicking += new RedirectPicking(prc_redirectPicking);
            pp.Observers.Add(prc);
            CommandProcessor.getCommandProcessor().SendCommandSyncronous(pp);      

        }

        void prc_redirectPicking(object obj)
        {
            RayTestInfo ri = obj as RayTestInfo;
            bla.Locomotion.DesiredSpeed = 15;
            bla.Locomotion.MaxRotation = 150;
            bla.Locomotion.MaxSpeed = 5;
            bla.Locomotion.DesiredPosition = ri.ImpactPosition ;

            Drawing.ClearAll();    
            Drawing.Draw3dLine(ri.ImpactPosition, ri.ImpactPosition + Vector3.Up* 20, Color.Red);
            Drawing.DrawCircleOrDisk(5, Vector3.Up, ri.ImpactPosition, Color.Purple, 100, true, true);
        }

    }
}

